package org.mozhu.simple.rpc.server;

import org.mozhu.simple.rpc.server.network.RpcChannel;
import org.mozhu.simple.rpc.server.network.Selector;

import java.io.IOException;
import java.net.Socket;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class AbstractServerThread implements Runnable {

    private CountDownLatch startupLatch = new CountDownLatch(1);

    private volatile CountDownLatch shutdownLatch = new CountDownLatch(0);

    private AtomicBoolean alive = new AtomicBoolean(true);


    public abstract void wakeup();

    public void shutdown() {
        alive.set(false);
        wakeup();
        try {
            shutdownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void awaitStartup() {
        try {
            startupLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    protected void startupComplete() {
        // Replace the open latch with a closed one
        shutdownLatch = new CountDownLatch(1);
        startupLatch.countDown();
    }

    protected void shutdownComplete() {
        shutdownLatch.countDown();
    }

    protected Boolean isRunning() {
        return alive.get();
    }

    public void close(Selector selector, String connectionId) {
        RpcChannel channel = selector.channel(connectionId);
        if (channel != null) {
            selector.close(connectionId);
        }
    }

    public void close(SocketChannel channel) {
        if (channel != null) {
            Socket socket = channel.socket();
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
